package com.myioc.entity;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * 
 * @author My
 *
 */
public class mysqlClassPashXmlApplicationContext {
	
	
	Map<String,Object> map=new HashMap<String,Object>();
	
	private Document document=null;
	
	public mysqlClassPashXmlApplicationContext(String path) {
		
		try {
			paramXML(path);
			
			setValue();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
			
			
		
	}
	
	private void setValue() throws Exception {
		
		
		
		Set<Entry<String,Object>> entrySet = map.entrySet();
		for (Entry<String, Object> entry : entrySet) {
			
			Object entity = entry.getValue();
			Class<? extends Object> clazz = entity.getClass();
			
			
			//2初始化里面的值
			//得到类下面的方法
			Method[] methods = clazz.getDeclaredMethods();
			
			//得到配置文件里属性的key和value
			@SuppressWarnings("unchecked")
			List<Element> propertylists = document.selectNodes("//bean/property");
			
			for (Element property : propertylists) {
				String propertyName = property.attributeValue("name");
				String propertyValue = property.attributeValue("value");
				
				// 有ref的情况
				
				String propertyref = property.attributeValue("ref");
				
				//====================================如果ref存在
				if(null !=propertyref){
//					System.out.println("xx");
					
					//得到ref的对象
					Object refObj = map.get(propertyref);
					
					Method[] refMethods = refObj.getClass().getDeclaredMethods();
					
					//遍历实体类的方法，调用set的方法将值设进去
					for (Method method : refMethods) {
//						setName
						String methodName = method.getName();
//						System.err.println(methodName);
						
						if(methodName.equalsIgnoreCase("set"+propertyName)){
							//得到每个方法的参数类型列表
							Class<?>[] parameterTypes = method.getParameterTypes();
							//第一个参数类型
							Class<?> parameterType = parameterTypes[0];
							
							String lx = parameterType.getName();
							if("int".equals(lx) || "java.lang.Integer".equals(lx)){
								method.invoke(refObj, Integer.parseInt(propertyValue));
							}else if("String".equals(lx) || "java.lang.String".equals(lx)){
								method.invoke(refObj,propertyValue);
							}
							
						}
					}
				}
				
				
				//==================不存在ref的时候===================
				
				//age,23				name,lihao
//				System.out.println(propertyName+","+propertyValue);
				
				//遍历实体类的方法，调用set的方法将值设进去
				for (Method method : methods) {
//					setName
					String methodName = method.getName();
//					System.err.println(methodName);
					
					if(methodName.equalsIgnoreCase("set"+propertyName)){
						//得到每个方法的参数类型列表
						Class<?>[] parameterTypes = method.getParameterTypes();
						//第一个参数类型
						Class<?> parameterType = parameterTypes[0];
						
						String lx = parameterType.getName();
						if("int".equals(lx) || "java.lang.Integer".equals(lx)){
							method.invoke(entity, Integer.parseInt(propertyValue));
						}else if("String".equals(lx) || "java.lang.String".equals(lx)){
							method.invoke(entity,propertyValue);
						}
//						break;
					}
				}
			}
		}
		
	}

	/**
	 * 通过dom4j解析xml文档
	 * @param path
	 * @throws Exception
	 */
	private void paramXML(String path) throws Exception {
		
		SAXReader reader=new SAXReader();
		document = reader.read(new File(path));
		@SuppressWarnings("unchecked")
		List<Element> lists = document.selectNodes("//bean");
		
		for (Element element : lists) {
			
			String id = element.attributeValue("id");
			String name = element.attributeValue("class");
			//得到类
			Class<?>  clazz= Class.forName(name);
			
			//1得到对象实体
			Object obj = clazz.newInstance();
			map.put(id,obj);
			
		}
	}
	
	
	
	
	
	/**
	 *  得到对象
	 * @param key
	 * @return
	 */
	public Object getBean(String key) {
		
		return map.get(key);
	}

}
